package xmla

import(
	"encoding/xml"
	"io"
	"strconv"
)
type RowSet struct{
	CatalogName string
	CubeName string
	DimensionUniqueName string
	HierarchyUniqueName string
	LevelUniqueName string
	LevelNumber uint8
	MemberOrdinal uint8
	MemberName string
	MemberUniqueName string
	MemberType int8
	MemberCaption string
	ChildrenCardinality uint8
	ParentLevel uint8
	ParentUniqueName string
	ParentCount uint8
	MemberKey uint8
	IsPlaceHolderMember bool
	IsDataMember bool
}

func NewRowSets(d *xml.Decoder)([]RowSet,error){
	return parseDecoder(d)
}

func parseDecoder(d *xml.Decoder) (rowSets []RowSet, err error) {
	i:=-1
	rowBegin:=false
    curAttr:=""
	lab:
	var rowSet *RowSet
	for {
		t, err := d.Token()
		if err == io.EOF {
			break
		}
		if err != nil {
			return nil, err
		}
		switch t := t.(type) {
		case xml.EndElement:
			if t.Name.Local=="row" {
				rowSets=append(rowSets,*rowSet)
				rowBegin=false
				curAttr=""
			}
		case xml.StartElement:
			if t.Name.Local=="Fault" {
				return nil,NewErrSoapFault(d);
			}else if t.Name.Local=="row" {
				i++;
				rowBegin=true
				rowSet=new(RowSet)
			}else{
				if rowBegin {
					curAttr=t.Name.Local
				}
			}
		case xml.CharData:
		    text:=string(t)
			switch curAttr{
				case "CATALOG_NAME":
				rowSet.CatalogName=text
				case "CUBE_NAME":
				rowSet.CubeName=text
				case "DIMENSION_UNIQUE_NAME":
				rowSet.DimensionUniqueName=text
				case "HIERARCHY_UNIQUE_NAME":
				rowSet.HierarchyUniqueName=text
				case "LEVEL_UNIQUE_NAME":
				rowSet.LevelUniqueName=text
				case "LEVEL_NUMBER":
				if cc,err:=strconv.Atoi(text);err==nil{
					rowSet.LevelNumber=uint8(cc)
				}
				case "MEMBER_ORDINAL":
				if cc,err:=strconv.Atoi(text);err==nil{
					rowSet.MemberOrdinal=uint8(cc)
				}
				case "MEMBER_NAME":
				rowSet.MemberName=text
				case "MEMBER_UNIQUE_NAME":
				rowSet.MemberUniqueName=text
				case "MEMBER_TYPE":
				if cc,err:=strconv.Atoi(text);err==nil{
					rowSet.MemberType=int8(cc)
				}
				
				case "MEMBER_CAPTION":
				rowSet.MemberCaption=text
				case "CHILDREN_CARDINALITY":
				if cc,err:=strconv.Atoi(text);err==nil{
					rowSet.ChildrenCardinality=uint8(cc)
				}
				case "PARENT_LEVEL":
				if cc,err:=strconv.Atoi(text);err==nil{
					rowSet.ParentLevel=uint8(cc)
				}
				case "PARENT_UNIQUE_NAME":
				rowSet.ParentUniqueName=text
				case "PARENT_COUNT":
			    if cc,err:=strconv.Atoi(text);err==nil{
					rowSet.ParentCount=uint8(cc)
				}
				case "MEMBER_KEY":
				if cc,err:=strconv.Atoi(text);err==nil{
					rowSet.MemberKey=uint8(cc)
				}
				case "IS_PLACEHOLDERMEMBER":
				if b,err:=strconv.ParseBool(text);err==nil{
					rowSet.IsPlaceHolderMember=b
				}
				case "IS_DATAMEMBER":
				if b,err:=strconv.ParseBool(text);err==nil{
					rowSet.IsDataMember=b
				}
			}
		case xml.Comment:
			goto lab
		case xml.ProcInst:
			goto lab
		}
	}
	if i==-1 {
		err=ErrDiscoverResponse{
			ErrorCode:"norow",
			Description:"返回结果为空！",
			Source:"MSAS",
			HelpFile:"请检查数据设置是否正确！",
		}
		return nil,err
	}
	return rowSets,err
}